package com.wyj.config;

import com.wyj.pojo.Configuration;
import com.wyj.pojo.MapperedStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;


/**
 * @author wuyijie
 * @description: TODO sql配置文件解析类。
 * @date 2021/10/30 1:19 下午
 */
public class XMLMapperBuilder {
    /**
     * 基本类型、包装类型、String类型
     */
    private static final Map<String, String> DEFAULT_TYPE_MAP = new HashMap<>();

    static {
        DEFAULT_TYPE_MAP.put("int", "java.lang.Integer");
        DEFAULT_TYPE_MAP.put("double", "java.lang.Double");
        DEFAULT_TYPE_MAP.put("long", "java.lang.Long");
        DEFAULT_TYPE_MAP.put("short", "java.lang.Short");
        DEFAULT_TYPE_MAP.put("byte", "java.lang.Byte");
        DEFAULT_TYPE_MAP.put("boolean", "java.lang.Boolean");
        DEFAULT_TYPE_MAP.put("char", "java.lang.Character");
        DEFAULT_TYPE_MAP.put("float", "java.lang.Float");

    }

    private Configuration configuration;

    public Configuration getConfiguration() {
        return configuration;
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    public XMLMapperBuilder(Configuration configuration) {
        this.configuration = configuration;
    }

    /**
     * TODO: sql解析方法
     *
     * @param inputStream 配置文件字节流
     * @author wuyijie
     * @date 2021/10/30 1:19 下午
     */
    public void parse(InputStream inputStream) throws DocumentException, ClassNotFoundException {
        Document read = new SAXReader().read(inputStream);
        Element rootElement = read.getRootElement();
        String namespace = rootElement.attributeValue("namespace");

        List<Node> mapperList = rootElement.selectNodes("//select | //update | //delete | //insert");
        for (Node node : mapperList) {
            Element element = (Element) node;
            String id = element.attributeValue("id");
            // 节点名称《标签名称》
            String nodeName = element.getName().toUpperCase(Locale.ROOT);
            SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName);
            String resultType = element.attributeValue("resultType");
            String parameterType = element.attributeValue("parameterType");
            String textTrim = element.getTextTrim();

            Class<?> resultTypeClazz = this.getClazz(resultType);
            Class<?> parameterTypeClazz = this.getClazz(parameterType);

            MapperedStatement mapperedStatement = new MapperedStatement();
            String key = namespace + "." + id;
            mapperedStatement.setId(id);
            mapperedStatement.setSqlCommandType(sqlCommandType);
            mapperedStatement.setResultType(resultTypeClazz);
            mapperedStatement.setParameterType(parameterTypeClazz);
            mapperedStatement.setSql(textTrim);

            this.configuration.getMapperedStatementMap().put(key, mapperedStatement);
        }
    }


    /**
     * TODO: 根据对象全路径，获取其clazz
     *
     * @param type
     * @return java.lang.Class<?>
     * @author wuyijie
     * @date 2021/10/30 2:48 下午
     */
    private Class<?> getClazz(String type) throws ClassNotFoundException {
        if (DEFAULT_TYPE_MAP.containsKey(type)) {
            return Class.forName(DEFAULT_TYPE_MAP.get(type));
        }
        if (type == null) {
            throw new RuntimeException("参数类型未找到");
        }
        return Class.forName(type);
    }
}
